home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / source.exe / POSIX / SH / STD / STDC / VPRINTF.C < prev   
C/C++ Source or Header  |  1992-07-13  |  5KB  |  236 lines

  1. #if __STDC__
  2. #include <stdarg.h>
  3. #else
  4. #include <varargs.h>
  5. #endif
  6. #include <stdio.h>
  7.  
  8. #define    BUF    40        /* buffer for int -> string conversion */
  9.  
  10. int
  11. #if __STDC__
  12. vprintf(Const char *fmt, va_list va) {
  13. #else
  14. vprintf(fmt, va) char *fmt; va_list va; {
  15. #endif
  16.     return vfprintf(stdout, fmt, va);
  17. }
  18.  
  19. int
  20. #if __STDC__
  21. vfprintf(register FILE *f, register Const char *fmt, register va_list va) {
  22. #else
  23. vfprintf(f, fmt, va) register FILE *f; register char *fmt; register va_list va; {
  24. #endif
  25.     register int c;
  26.     int pos = 0;            /* todo: implement */
  27.  
  28.     while ((c = *fmt++))
  29.         if (c == '%') {
  30.         long n;
  31.         register unsigned long u;
  32.         char buf [BUF+1];
  33.         register char *p = buf + BUF;
  34.         register enum {
  35.             FF_ALT = 0x01, /* #, alternate format */
  36.             FF_SHORT = 0x02, /* h, short arg */
  37.             FF_LONG = 0x04,    /* l, long arg */
  38.             FF_ZERO = 0x08,    /* 0, zero fill */
  39.             FF_LEFT = 0x10,    /* -, left adjust */
  40.             FF_PREC = 0x20,    /* .*, precision */
  41.             FF_NEG = 0x40,    /* signed arg */
  42.             FF_PUTS = 0x80,    /* fputs(p, f) */
  43.             FF_DEFAULT = 0
  44.         } flags = FF_DEFAULT;
  45.         int sign = '-';    /* sign: [ +-] */
  46.         int width = 0, prec = 0; /* width, precision */
  47.  
  48.         *p = 0;
  49.  
  50.         /* scan flag characters */
  51.         for (c = *fmt++; ; c = *fmt++) switch (c) {
  52.           case '0':
  53.             flags |= FF_ZERO;
  54.             break;
  55.  
  56.           case '#':        /* alternate format */
  57.             flags |= FF_ALT;
  58.             break;
  59.  
  60.           case ' ':        /* blank sign */
  61.             sign = ' ';
  62.             break;
  63.           case '+':        /* +/- sign */
  64.             sign = '+';
  65.             break;
  66.  
  67.           case '-':        /* left just. */
  68.             flags |= FF_LEFT;
  69.             break;
  70.  
  71.           default:
  72.             goto Frogs;
  73.         }
  74.       Frogs:
  75.  
  76.         /* scan width */
  77.           if (c == '*') {        /* width from arg list */
  78.             width = va_arg(va, int);
  79.             c = *fmt++;
  80.         } else
  81.             while ('0' <= c && c <= '9') {
  82.                 width = width*10 + (c-'0');
  83.                 c = *fmt++;
  84.             }
  85.  
  86.         if (c == '.') {        /* scan precision */
  87.             flags |= FF_PREC;
  88.             c = *fmt++;
  89.             if (c == '*') {    /* precision from arg list */
  90.                 prec = va_arg(va, int);
  91.                 c = *fmt++;
  92.             } else
  93.                 while ('0' <= c && c <= '9') {
  94.                     prec = prec*10 + (c-'0');
  95.                     c = *fmt++;
  96.                 }
  97.         }
  98.  
  99.         /* length modifiers */
  100.         if (c == 'h') {
  101.             flags |= FF_SHORT;
  102.             c = *fmt++;
  103.         } else if (c == 'l') {
  104.             flags |= FF_LONG;
  105.             c = *fmt++;
  106.         }
  107.  
  108.         /* do conversion */
  109.         switch (c) {
  110.           case '%':        /* %% -> % */
  111.             putc(c, f);
  112.             pos ++;
  113.             break;
  114.  
  115.           case 'p':        /* pointer */
  116.             *--p = '}';
  117.             u = (unsigned long) va_arg(va, Void*);
  118.             do {
  119.                 *--p = "0123456789ABCDEF"[u%16];
  120.                 u /= 16;
  121.             } while (u != 0);
  122.             *--p = '{';
  123.             flags |= FF_PUTS;
  124.             break;
  125.  
  126.           case 'n':        /* save position */
  127.             *va_arg(va, int*) = pos;
  128.             break;
  129.  
  130.           case 'c':        /* character */
  131.             u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
  132.               : (flags&&FF_LONG) ? va_arg(va, unsigned long)
  133.               : va_arg(va, unsigned int);
  134.             *--p = u;
  135.             flags |= FF_PUTS;
  136.             break;
  137.  
  138.           case 's':        /* string */
  139.             p = va_arg(va, char *);
  140.             if ((flags&FF_PREC) && strlen(p) > prec) {
  141.                 pos += prec;
  142.                 while (--prec >= 0)
  143.                     putc(*p++, f);
  144.                 break;
  145.             }
  146.             flags |= FF_PUTS;
  147.             break;
  148.  
  149.           case 'i': case 'd': case 'u': /* decimal */
  150.             if (c != 'u') {    /* signed */
  151.                 n = (flags&FF_SHORT) ? va_arg(va, short)
  152.                   : (flags&&FF_LONG) ? va_arg(va, long)
  153.                   : va_arg(va, int);
  154.                 if (n < 0)
  155.                     flags |= FF_NEG;
  156.                 u = (n < 0) ? -n : n;
  157.             } else
  158.                 u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
  159.                   : (flags&&FF_LONG) ? va_arg(va, unsigned long)
  160.                   : va_arg(va, unsigned int);
  161.             do {
  162.                 *--p = '0' + u%10;
  163.                 u /= 10;
  164.             } while (u != 0);
  165.             prec -= buf+BUF - p;
  166.             while (--prec >= 0)
  167.                 *--p = '0';
  168.             if (flags&FF_NEG)
  169.                 *--p = '-';
  170.             else
  171.                 if (sign != '-')
  172.                     *--p = (sign == '+') ? '+' : ' ';
  173.             flags |= FF_PUTS;
  174.             break;
  175.  
  176.           case 'x': case 'X':    /* hex, Hex */
  177.             u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
  178.               : (flags&&FF_LONG) ? va_arg(va, unsigned long)
  179.               : va_arg(va, unsigned int);
  180.             do {
  181.                 *--p = "0123456789ABCDEF"[u%16];
  182.                 u /= 16;
  183.             } while (u != 0);
  184.             prec -= buf+BUF - p;
  185.             while (--prec >= 0)
  186.                 *--p = '0';
  187.             if (flags&&FF_ALT)
  188.                 *--p = 'x', *--p = '0';
  189.             flags |= FF_PUTS;
  190.             break;
  191.  
  192.           case 'o':        /* octal */
  193.             u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
  194.               : (flags&&FF_LONG) ? va_arg(va, unsigned long)
  195.               : va_arg(va, unsigned int);
  196.             do {
  197.                 *--p = '0' + u%8;
  198.                 u /= 8;
  199.             } while (u != 0);
  200.             prec -= buf+BUF - p;
  201.             while (--prec >= 0)
  202.                 *--p = '0';
  203.             if (flags&&FF_ALT && *p != '0')
  204.                 *--p = '0';
  205.             flags |= FF_PUTS;
  206.             break;
  207.  
  208.           default:        /* todo: error */
  209.             putc('%', f);
  210.             putc(c, f);
  211.             pos += 2;
  212.             break;
  213.         }
  214.  
  215.         /* copy adjusted string "p" to output */
  216.         if (flags&FF_PUTS) {
  217.             int len = strlen(p);
  218.             int pad = width - len;
  219.             if (!(flags&FF_LEFT))
  220.                 while (--pad >= 0)
  221.                     putc((flags&FF_ZERO) ? '0' : ' ', f);
  222.             while (*p)
  223.                 putc(*p++, f);
  224.             if ((flags&FF_LEFT))
  225.                 while (--pad >= 0)
  226.                     putc(' ', f);
  227.             pos += (len < width) ? width : len;
  228.         }
  229.         } else {            /* ordinary character */
  230.         putc(c, f);
  231.         pos ++;
  232.         }
  233.     return pos;
  234. }
  235.  
  236.